The approaches described in this section could be pursued, but are not necessarily approaches that have been previously conceived or pursued. Therefore, unless otherwise indicated herein, the approaches described in this section are not prior art to the claims in this application and are not admitted to be prior art by inclusion in this section.
In a data processing system, various components may interact to request services from other components or provide services to other components in a system. A “component” is an entity that can carry a unique identifier and provide a service, and may be software, hardware, or a combination of hardware and software. Other examples of “components” include modules, processes, agents, Object Oriented classes (referred to hereinafter as “OO classes”), instances of Object Oriented classes (referred to hereinafter as “OO instances”), programs, etc.
For example, a computer user may want to move a file into a particular folder. The folder needs to allocate sufficient storage space in order to receive the file in that folder. When the user initiates the move, a process is activated to perform the move operation. The process interacts with the folder to determine if the folder has sufficient space for storing the file. In this example, the process is a component that requests a service, i.e., moving the file, and the folder is a component that provides the service, i.e., receiving and storing the file.
Components that request services and the components that provide the requested services are “coupled” to each other because they exchange information. Components may be tightly coupled or loosely coupled. Generally, coupling may be defined as the measure of the strength of association established by a connection from one module to another, as described in W. Stevens, G. Myers, L. Constantine, Structured Design, IBM Systems Journal, vol. 13, pp. 115–139, 1974. Relatedness of program parts is how the concept is widely understood, as in R. G. Fichman, C. F. Kemerer, Adoption of Software Engineering Process: the case of object orientations, SMR, vol. 34, pp. 7–22, 1993; S. R. Chidamber, C. F. Kemerer, A metrics suite for object oriented design, IEEE Transaction on Software Engineering, vol. 20, pp. 476–493, 1994.
The nature of the coupling between the components is determined, for example, by the type or level of services that are requested or provided. For example, a first process may provide a second process unlimited access to its data, however, the first process may provide a third process only limited access to its data. The first process has a different level of coupling with the second process than with the third process. Thus, in this example, the level of the service provided determines the nature of the coupling.
In a second example, a folder may require that one file is password-protected in order to move the file the folder. However, the folder may require that another file be in a particular format. Thus, in this example, the type of service provided determines the nature of the coupling between the folder and the files. Components that request or provide services need to communicate to one another the nature of coupling that they permit.
In one past approach used in the context of programming in procedural languages, coupling has been defined in terms of one of a plurality of “levels of coupling”:                (1) Content: one module branches into a second module to modify the data or the instructions of the second module,        (2) Common: Where two modules access the same global variable,        (3) External: two modules access global variables, which are external to the two modules,        (4) Control: one module exercises control over a second module by passing information into a second module that affects the behavior of the second module, and the information may be a parameter or instructions for the second module,        (5) Stamp: two modules receive the same record as a parameter,        (6) Data: two modules communicate via parameters, and        (7) None: none of the above layers apply to the two modules in question.        
However, this approach has numerous disadvantages. First, the coupling levels approach has been used only with procedural programs or modules. The coupling levels approach cannot be used for other types of components, such as OO instances or agents. Second, the nature of the coupling between the modules is static. Typically, the nature of the coupling is hard-coded into the modules and does not change while the modules are executing.
The Common Object Request Broker Architecture or “CORBA” has been used in a second past approach for components to communicate the nature of allowed coupling. In the CORBA approach, OO instances register with a broker process, indicating what services the OO instances provide or request. When an OO instance registers with the broker requesting a certain set of services, the broker provides information to the requesting OO instance indicating which OO instances provide those services. Thus, the broker assists newly introduced objects in finding needed services.
However, this approach also has numerous disadvantages. First, CORBA requires an extensive infrastructure or “middleware” that includes a broker. Second, this approach only applies to OO instances. Third, the nature of the coupling is static. For example, once the OO instances have registered with the broker, they are not allowed to modify the nature of their coupling. Therefore, the CORBA approach cannot account for changes in objects or services. Further, the CORBA approach is workable only for OO instances and not for other kinds of components.
In still another past approach, a self-controlled, non-brokered mechanism is provided for determining coupling; this approach is used, for example, in platforms based on mobile agents, such as Voyager, Grasshopper, and Jini. These platforms control the level of interaction of agents internally by having a homogeneous environment in which all mobile agents are the same, and self-scheduling execution of processes and sub-processes on different servers. Both the form of the internal data structures and the level of interaction of agents are static.
Coupling involves several aspects of express inter-component relationships. Some of these relationships are statically pre-tuned, at the time that component specifications are created, such type of connection, complexity of an interface, type of information flow along the connection. Other relationships are dynamically set, such as binding time, duration of the connection, coupling state, etc.
However, regardless of the kind of static coupling that may be defined by design, the right behavior of components is best determined when the coupling actually executes. Further, for static coupling to succeed, the specification phase of a component must correctly and explicitly specify particular types of couplings, to handle them automatically. However, accurate specification rarely occurs. Thus, there is a need for approaches that allow interacting components to dynamically exchange and set the nature of the coupling that they use.
Adaptation is a property of an entity to constrain its behavior according to environmental conditions. An algorithm that can learn and change its behavior by comparing the results of its actions with the goals that it is designed to achieve is called an “adaptive algorithm.” An “adaptive system” can understand and predict actions looking for patterns within its behavior or within its environment.
Special adaptive systems have been designed in an ad-hoc manner, based on a narrow set of requirements, such as described in L. Ardissono, L. Console, I. Torre, An Adaptive System for the personalized access to news, AI Communications, ISSN 0921-7126, IOS Press; I. Foster, A. Roy, A QoS Architecture that Combines Resource Reservation and Application Adaptation, IWQoS 2000; or Pearlman, V. Welch, I Foster, C. Kesselman, S. Tuecke, A Community Authorization Service for Group Collaboration, ISI, The University of Southern California.
Further, most prior approaches focus on adaptive control in which three distinct mechanisms are used: (i) actuators that permit online control of resource allocations, application behavior, etc.; (ii) sensors that allow monitoring of status, behavior, or other parameters; and (iii) decision procedures that allow entities to respond to sensor information, by invoking actuators.
However, these approaches have not been applied in the context of service coupling. Indeed, there is relatively little literature at all concerning coupling in highly distributed software architectures. Also, little or no solutions exist for monitoring and controlling coupling behavior in systems with an embedded degree of automation. In these cases, coupling answers the question of how much of one system component must be known in order to understand another component(s).
Between loosely coupled components and tightly coupled components, many discrete levels have been identified. It is assumed that two components may have a predefined level of coupling or a few levels can be pre-tuned to be switched. Loosely coupled components have very little information or none on each other. Generally, only information is passed. In general, this kind of interaction is initiated through a trader or other special component mediating the interactions. Tightly coupled components/systems require the interacting entities have detailed information on interface type, interface name, type of interface matching, locations of entities, types of entities, and names of entities.
In programming, coupling as an abstract concept is manifested in the need to consider something about another module when coding or modifying another component. However, extensions in programming paradigms such as agent based programming, context-based programming, nomadic-process-based programming, delegation-based programming, have changed and complicated the coupling landscape. The interaction of components is now extremely diversified and complex, especially when several of these technologies are simultaneously used. Coding is no longer the only concern; interaction types and behavior become a concern as well.
Further, coupling greatly complicates testing of software components, even when coupling is addressed in a static form. Code-based coupling techniques have been used as a measure to derive testing methods for system's structural complexity. In large, monolithic systems comprising millions of lines of code, testing at the code level based on classic theory of related tasks and their interaction become problematic.
Classical coupling approaches are statically defined, mainly based on the type of interchanged data, and are used only in the early stages of the software design lifecycle, such as the specification stage. There are very few concerns about the behavior of interacting components, or to their interacting behavior, when the interaction occurs. As a result, distributed architectures vary from those that provide statically defined, loose coupling to those with tight coupling ranges. No mechanisms have been possible to establish an adequate coupling, in a dynamic way, since component behaviors may change, or new components with unknown behaviors may join an existing community of components. As a result, no automatic management systems have been allowed to capture and remedy potential incorrect interaction at run time.
Based on the foregoing, there is a clear need for managing coupling between components in a way that is not static and not limited to a particular type of component. In particular, there is a need for a way to adaptively or dynamically couple components in a distributed system.